package com.hcl.security.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {

    public static void main(String[] args) {
        // **自定义 payload**
        Map<String, Object> claims = new HashMap<>();
        claims.put("role", "admin");

        // **生成 Token**
        String token = JwtUtil.generateToken(claims, "user123");
        System.out.println("JWT Token: " + token);
    }

    // **密钥（必须是 Base64 编码的 256-bit Key，否则会报错）**
    private static final String SECRET_KEY = "111111111111111111111111111111111111111111111111111111111111111111111111111111111111";

    // **Token 过期时间（1小时）**
    private static final long EXPIRATION_TIME = 1000 * 60 * 60;

    // **获取密钥**
    private static Key getSigningKey() {
        return Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET_KEY));
    }

    /**
     * 生成 JWT
     *
     * @param claims  自定义 payload 数据
     * @param subject 用户身份标识（如用户名）
     * @return JWT 字符串
     */
    public static String generateToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .claims(claims) // 自定义 payload
                .subject(subject) // 设置 subject（用户名）
                .issuedAt(new Date()) // 签发时间
                .expiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 过期时间
                .signWith(getSigningKey()) // 使用密钥进行签名（新 API）
                .compact();
    }

    /**
     * 解析 JWT
     *
     * @param token JWT 字符串
     * @return 解析后的 Claims（包含用户信息）
     */
    public static Claims parseToken(String token) {
        try {
            return Jwts.parser()
                    .verifyWith((SecretKey) getSigningKey()) // 验证密钥（新方法）
                    .build()
                    .parseSignedClaims(token) // 解析 Token（新方法）
                    .getPayload(); // 获取 payload
        } catch (Exception e) {
            // Token 无效或已过期
            return null;
        }
    }

    /**
     * 获取 JWT 的 Subject（通常是用户名）
     *
     * @param token JWT 字符串
     * @return subject
     */
    public static String getSubject(String token) {
        Claims claims = parseToken(token);
        return (claims != null) ? claims.getSubject() : null;
    }

    /**
     * 验证 JWT 是否过期
     *
     * @param token JWT 字符串
     * @return 是否过期（true：已过期，false：未过期）
     */
    public static boolean isTokenExpired(String token) {
        Claims claims = parseToken(token);
        return (claims == null || claims.getExpiration().before(new Date()));
    }

    /**
     * 刷新 JWT（重新生成 Token）
     *
     * @param token 旧的 JWT
     * @return 新的 JWT
     */
    public static String refreshToken(String token) {
        Claims claims = parseToken(token);
        if (claims != null) {
            return generateToken(claims, claims.getSubject());
        }
        return null;
    }
}
